package com.longma.server.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.longma.server.dao.DailyDataDAO;
import com.longma.server.dao.MonthDataDAO;
import com.longma.server.entity.DailyData;
import com.longma.server.entity.MonthData;
import com.longma.server.entity.Yuncang;
import com.longma.server.pojo.vo.home.PointVO;
import com.longma.server.service.IMonthDataService;
import com.longma.server.service.IYuncangUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 月发电量、用电量数据  服务类
 */
@Service
@Transactional
public class MonthDataServiceImpl implements IMonthDataService {
    @Autowired
    private MonthDataDAO monthDataDAO;

    @Autowired
    private DailyDataDAO dailyDataDAO;

    @Autowired
    private IYuncangUserService yuncangUserService;

    /**
     * 更新月发发电量、月电量数据
     */
    @Override
    public void updateMonthData() {
        // 获取当前月份1号
        int year = LocalDateTime.now().getYear();
        int month = LocalDateTime.now().getMonthValue();
        LocalDate firstDay = LocalDate.of(year,month,1);

        // 获取当前月份每日数据
        List<DailyData> dailyDatas = dailyDataDAO.list(Wrappers.<DailyData>lambdaQuery().ge(DailyData::getDate,firstDay));

        if(CollUtil.isEmpty(dailyDatas)){
            return ;
        }

        // 保存云仓id -> 月统计数据
        Map<Integer,Double> consumptions = new HashMap<>();
        Map<Integer,Double> generations = new HashMap<>();

        for(DailyData dailyData:dailyDatas){
            // 新增
            if(!consumptions.containsKey(dailyData.getYuncangId())){
                consumptions.put(dailyData.getYuncangId(),dailyData.getConsumption());
                generations.put(dailyData.getYuncangId(),dailyData.getGeneration());
            }else{
                consumptions.put(dailyData.getYuncangId(),consumptions.get(dailyData.getYuncangId()) + dailyData.getConsumption());
                generations.put(dailyData.getYuncangId(),generations.get(dailyData.getYuncangId()) + dailyData.getGeneration());
            }
        }

        // 删除这些云仓的数据 然后更新
        monthDataDAO.remove(Wrappers.<MonthData>lambdaQuery().eq(MonthData::getYear,year)
                .eq(MonthData::getMonth,month)
                .in(MonthData::getYuncangId, consumptions.keySet()));

        // 构建插入实体
        List<MonthData> monthDatas = new ArrayList<>();
        for(Map.Entry<Integer,Double>  consumption : consumptions.entrySet()){
            MonthData monthData = new MonthData();
            monthData.setYear(year);
            monthData.setMonth(month);
            monthData.setYuncangId(consumption.getKey());
            monthData.setConsumption(consumption.getValue());
            monthData.setGeneration(generations.get(consumption.getKey()));
            monthDatas.add(monthData);
        }

        // 判断月数据是否存在
        monthDataDAO.saveBatch(monthDatas);
    }

    /*
     * 根据云仓id获取当月发电量、用电量
     */
    @Override
    public MonthData getMonthData(Integer yuncangId) {
        int year = LocalDateTime.now().getYear();
        int month = LocalDateTime.now().getMonthValue();

        MonthData monthData = monthDataDAO.getOne(Wrappers.<MonthData>lambdaQuery().eq(MonthData::getYuncangId,yuncangId)
        .eq(MonthData::getYear,year)
        .eq(MonthData::getMonth,month));

        if(monthData == null){
            monthData = new MonthData();
            monthData.setYuncangId(yuncangId);
            monthData.setConsumption(0.0);
            monthData.setGeneration(0.0);
            monthData.setYear(year);
            monthData.setMonth(year);

        }
        return monthData;
    }

    /**
     * 获取登录用户所拥有云仓月用电合计曲线
     */
    @Override
    public List<PointVO> getMonthConsumptionCurve() {
        return getMonthCurve(false);
    }

    /**
     * 获取登录用户所拥有云仓月发电合计曲线
     */
    @Override
    public List<PointVO> getMonthGenerationCurve() {
        return getMonthCurve(true);
    }


    /**
     * 月发电or月电曲线
     * @param generation: true 发电  false用电
     */
    private List<PointVO> getMonthCurve(boolean generation) {
        // 初始化数据
        List<PointVO> res = new ArrayList<>();
        // 获取当前年月
        int year = LocalDateTime.now().getYear();
        int month = LocalDateTime.now().getMonthValue();

        // 按顺序存放当前月每日用电量or发电量
        Calendar today = Calendar.getInstance();
        int maxDay = today.getMaximum(Calendar.DAY_OF_MONTH);
        for(int i=1; i<=maxDay; i++){
            res.add(new PointVO(String.format("%04d-%02d-%02d",year,month,i),0.0));
        }

        // 获取云仓id
        List<Integer> yuncangIds = yuncangUserService.getYuncangs().stream().map(Yuncang::getId).collect(Collectors.toList());

        // 不存在云仓
        if (CollUtil.isEmpty(yuncangIds)){
            return res;
        }

        // 当前月第一天
        LocalDate firstDay = LocalDate.of(year,month,1);

        // 查询云仓日数据
        List<DailyData> dailyDatas = dailyDataDAO.list(Wrappers.<DailyData>lambdaQuery().ge(DailyData::getDate,firstDay)
                .in(DailyData::getYuncangId,yuncangIds));

        for(DailyData dailyData:dailyDatas){
            PointVO pointVO = res.get(dailyData.getDate().getDayOfMonth() - 1);
            if(generation) {
                pointVO.setValue(pointVO.getValue() + dailyData.getGeneration());
            }else {
                pointVO.setValue(pointVO.getValue() + dailyData.getConsumption());
            }
        }

        return res;
    }

}
